package com.gpj.sqlbuilder.template;

import com.gpj.sqlbuilder.constants.Constants;
import com.gpj.sqlbuilder.utils.TextUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @className LoopTemplate
 * @description TODO
 * @author GPJ
 * @date 2021/4/16 20:49
 * @version 1.0
 **/
public class LoopTemplate extends ElementTemplate{
	private static final String LOOP_START_MARK = "<for>";
	private static final String LOOP_TAIL_MARK = "</for>";

	private static final String ATTRIBUTE_KEY_ITEM = "item";
	private static final String ATTRIBUTE_KEY_INDEX = "index";
	private static final String ATTRIBUTE_KEY_COLLECTION = "collection";
	private static final String ATTRIBUTE_KEY_START = "start";
	private static final String ATTRIBUTE_KEY_SEPARATOR = "separator";
	private static final String ATTRIBUTE_KEY_END = "end";
	private static final String ATTRIBUTE_KEY_TYPE = "type";
	private static final String ATTRIBUTE_KEY_TYPE_LINE = "line";

	public LoopTemplate(int start, int tail, Template parent) {
		super(start, tail, parent);
	}

	@Override
	protected String getStartMark() {
		return LOOP_START_MARK;
	}

	@Override
	protected String getTailMark() {
		return LOOP_TAIL_MARK;
	}

	@Override
	protected void doBuild() {
		List collections = getCollection();
		if(collections.isEmpty()) return;

		String separator = getAttrSeparator();

		StringBuffer loopSql = new StringBuffer();
		for (int i = 0; i < collections.size(); i++) {
			// 设置item与index变量
			variables.put(getAttrIndex(), i);
			variables.put(getAttrItem(), collections.get(i));

			// 构建单次循环的SQL语句
			StringBuffer itemsql = builChildSql();
			if(StringUtils.isNotBlank(itemsql)){
				if(!isLine()){
					loopSql.append(removeEnter(itemsql)).append(separator).append(Constants.ENTER_MARK);
				}else{
					loopSql.append(itemsql).append(separator);
				}
			}
		}

		if(StringUtils.isBlank(loopSql)) return;

		sql.append(getAttrStart());
		// 处理循环体内回车符问题
		if(StringUtils.isNotBlank(separator)){
			int endIndex = separator.length();
			if(!isLine()){
				endIndex += Constants.ENTER_MARK.length();
			}
			sql.append(TextUtils.substr(0, -1 * endIndex, loopSql));
		}else{
			sql.append(loopSql);
		}
		sql.append(getAttrEnd()).append(Constants.ENTER_MARK);
		sql = text2Sql(sql);
	}

	/**
	 * 构建子类的SQL语句
	 */
	public StringBuffer builChildSql(){
		StringBuffer childSql = new StringBuffer();
		for (Template child : children) {
			child.build();

			if(isLine()){
				childSql.append(removeEnter(child.getSql()));
			}else{
				childSql.append(child.getSql());
			}
		}
		return childSql;
	}

	/**
	 * 去除结尾的回车符
	 * @param sql 待处理字符串
	 */
	private StringBuffer removeEnter(StringBuffer sql){
		if(sql.toString().trim().endsWith(Constants.ENTER_MARK)){
			int index = sql.lastIndexOf(Constants.ENTER_MARK);
			return TextUtils.substr(0, index, sql);
		}
		return sql;
	}

	/**
	 * 获取集合对象
	 */
	private List getCollection() {
		String collectionName = getAttribute(ATTRIBUTE_KEY_COLLECTION, "");
		Object collection = queryVariableByName(TextUtils.roundValue("${*}", collectionName));

		if(collection == null) return Collections.emptyList();

		if(collection instanceof Map){
			return Arrays.asList(((Map) collection).values().stream().toArray());
		}
		return (List) collection;
	}

	private String getAttrStart() {
		return getAttribute(ATTRIBUTE_KEY_START, "");
	}

	private String getAttrSeparator() {
		return getAttribute(ATTRIBUTE_KEY_SEPARATOR, "");
	}

	private String getAttrEnd() {
		return getAttribute(ATTRIBUTE_KEY_END, "");
	}

	private String getAttrItem() {
		return getAttribute(ATTRIBUTE_KEY_ITEM, "item");
	}

	private String getAttrIndex() {
		return getAttribute(ATTRIBUTE_KEY_INDEX, "loopindex");
	}

	private boolean isLine() {
		String type = getAttribute(ATTRIBUTE_KEY_TYPE, "");
		return StringUtils.equals(type, ATTRIBUTE_KEY_TYPE_LINE);
	}
}
